package com.tianyang.yukuaifu.rxservice.client;

import android.util.Log;

import com.tianyang.yukuaifu.common.interfaces.CommonConfig;
import com.tianyang.yukuaifu.common.interfaces.UrlConstants;
import com.tianyang.yukuaifu.common.service.DownloadCallBack;
import com.tianyang.yukuaifu.common.service.SPDownloadUtil;
import com.tianyang.yukuaifu.rxservice.BaseUploadClient;
import com.tianyang.yukuaifu.rxservice.SSLSocketClient;
import com.tianyang.yukuaifu.rxservice.interfaces.DownloadService;

import java.io.File;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.util.concurrent.TimeUnit;

import okhttp3.OkHttpClient;
import okhttp3.ResponseBody;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.gson.GsonConverterFactory;
import rx.Observer;

/**
 * Description：APP更新下载
 * Created by 薛勇军 on 2021/1/21
 */
public class DownloadClient extends BaseUploadClient {

    private static final String TAG = "RetrofitClient";

    private DownloadService downloadService;

    private static DownloadClient sIsntance;

    public static DownloadClient getInstance(String baseUrl) {
        if (sIsntance == null) {
            synchronized (DownloadClient.class) {
                if (sIsntance == null) {
                    sIsntance = new DownloadClient(baseUrl);
                }
            }
        }
        return sIsntance;
    }

    private DownloadClient(String baseUrl) {
        // 创建 OKHttpClient
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        builder.connectTimeout(UrlConstants.HTTP_TIMEOUT, TimeUnit.SECONDS);//连接超时时间
        // builder.writeTimeout(DEFAULT_READ_TIME_OUT,TimeUnit.SECONDS);//写操作 超时时间
        builder.readTimeout(UrlConstants.HTTP_TIMEOUT, TimeUnit.SECONDS);//读操作超时时间
        builder.sslSocketFactory(SSLSocketClient.getSSLSocketFactory());
        builder.hostnameVerifier(SSLSocketClient.getHostnameVerifier());
        Retrofit retrofit = new Retrofit.Builder()
                .client(builder.build())
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .baseUrl(baseUrl)
                .build();
        downloadService = retrofit.create(DownloadService.class);
    }

    public void downloadFile(final long range, final String url, final String fileName, final DownloadCallBack downloadCallback) {
        downloadService.executeDownload("bytes=" + Long.toString(range) + "-", url)
                .subscribe(new Observer<ResponseBody>() {

                    @Override
                    public void onNext(ResponseBody responseBody) {
                        RandomAccessFile randomAccessFile = null;
                        InputStream inputStream = null;
                        long total = range;
                        long responseLength = 0;
                        try {
                            byte[] buf = new byte[10240];
                            int len = 0;
                            responseLength = responseBody.contentLength();
                            inputStream = responseBody.byteStream();
                            String filePath = CommonConfig.APP_ROOT_PATH + CommonConfig.DOWNLOAD_DIR;
                            File file = new File(filePath, fileName);
                            File dir = new File(filePath);
                            if (!dir.exists()) {
                                dir.mkdirs();
                            }
                            randomAccessFile = new RandomAccessFile(file, "rwd");
                            if (range == 0) {
                                randomAccessFile.setLength(responseLength);
                            }
                            randomAccessFile.seek(range);

                            int progress = 0;
                            int lastProgress = 0;

                            while ((len = inputStream.read(buf)) != -1) {
                                randomAccessFile.write(buf, 0, len);
                                total += len;
                                SPDownloadUtil.getInstance().save(url, total);
                                lastProgress = progress;
                                progress = (int) (total * 100 / randomAccessFile.length());
                                if (progress > 0 && progress != lastProgress) {
                                    downloadCallback.onProgress(progress);
                                }
                            }
                            downloadCallback.onCompleted();
                        } catch (Exception e) {
                            Log.d(TAG, e.getMessage());
                            downloadCallback.onError(e.getMessage());
                            e.printStackTrace();
                        } finally {
                            try {
                                if (randomAccessFile != null) {
                                    randomAccessFile.close();
                                }

                                if (inputStream != null) {
                                    inputStream.close();
                                }

                            } catch (Exception e) {
                                e.printStackTrace();
                            }

                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        downloadCallback.onError(e.toString());
                    }

                    @Override
                    public void onCompleted() {
                    }
                });
    }
}
